package com.caishi.lkx.order.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zzw.common.entity.BaseService;
import com.zzw.common.exception.BizException;
import com.caishi.lkx.order.ienum.status.OrderStatus;
import com.caishi.lkx.order.ienum.type.OrderType;
import com.caishi.lkx.order.ienum.type.PaymentType;
import com.caishi.lkx.order.model.OrderDetailModel;
import com.caishi.lkx.order.model.OrderModel;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author by keray
 * date:2021/5/14 2:36 下午
 */
public interface IOrderService extends BaseService<OrderModel, String> {

    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/9/9 10:30</h3>
     * 订单编号生成
     * </p>
     *
     * @param orderModel
     * @return <p> {@link String} </p>
     * @throws
     */
    String generateOrderSn(@NotNull OrderModel orderModel);

    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/9/9 9:46</h3>
     * 创建订单的完整信息
     * </p>
     *
     * @param userId
     * @param type         订单类型
     * @param detailModels 订单详情
     * @param remark
     * @param paymentType  支付类型
     * @return <p> {@link OrderModel} </p>
     */
    @NotNull
    OrderModel previewOrder(String createdBy, String userId, OrderType type, List<OrderDetailModel> detailModels, String remark, PaymentType paymentType, String formula, Long price,Long groupId);

    @Transactional(rollbackFor = Exception.class)
    OrderModel createOrder(String createdBy, String userId, OrderType type, List<OrderDetailModel> detailModels, String remark, PaymentType paymentType, String formula, Long price, String entityId,Long groupId);

    @Transactional(rollbackFor = Exception.class)
    OrderModel createOrder(String createdBy, String userId, OrderType type, List<OrderDetailModel> detailModels, String remark, PaymentType paymentType, String formula, String entityId,Long groupId);

    @Transactional(rollbackFor = Exception.class)
    OrderModel createOrder(String createdBy, String userId, OrderType type, List<OrderDetailModel> detailModels, String remark, PaymentType paymentType, String formula,Long groupId);

    @Transactional(rollbackFor = Exception.class)
    OrderModel createOrder(String createdBy, String userId, OrderType type, List<OrderDetailModel> detailModels, String remark, PaymentType paymentType, String formula,Long groupId,String recommendId);


    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/9/5 14:17</h3>
     * 获取订单详情，包括了订单详情列表
     * </p>
     *
     * @param orderId
     * @return <p> {@link OrderModel} </p>
     * @throws
     */
    OrderModel orderDetail(String orderId, boolean detailList, boolean product, boolean payDetail);
    OrderModel orderDetail(OrderModel orderModel, boolean detailList, boolean product, boolean payDetail);


    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/9/5 14:22</h3>
     * 订单发货，将订单资产绑定到用户
     * </p>
     *
     * @param orderId
     * @return <p> {@link } </p>
     * @throws
     */
    void orderDelivery(String orderId);


    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/9/9 9:51</h3>
     * 计算订单价格
     * </p>
     *
     * @param orderModel
     * @return <p> {@link BigDecimal} </p>
     */
    @NotNull
    long computePrice(@NotNull OrderModel orderModel);


    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/10/16 14:00</h3>
     * 价格公式计算
     * </p>
     *
     * @param original
     * @param formula
     * @return <p> {@link BigDecimal} </p>
     * @throws
     */
    long priceFormulaCompute(long original, String formula);

    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/11/26 2:55 PM</h3>
     * 用户订单状态变更
     * </p>
     *
     * @param orderId
     * @param status
     * @return <p> {@link Boolean} </p>
     */
    void userOrderStatusChange(String orderId, OrderStatus status);
    void userOrderStatusChange(String orderId, OrderStatus status,String userId);
    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/11/27 2:04 PM</h3>
     * 获取订单三方支付时订单标题
     * </p>
     *
     * @param id
     * @return <p> {@link String} </p>
     * @throws
     */
    String getOrderOnlinePayTitle(String id);

    /**
     * 订单成功（收货状态）
     *
     * @param orderId
     */
    void orderSuccess(String orderId);

    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/9/10 13:59</h3>
     * 订单申请退款
     * </p>
     *
     * @param orderId    不跳过校验时 必须设置订单详情 商品详情
     * @param ownerCheck 是否校验本人申请
     * @param skipCheck  跳过检验
     * @throws BizException
     */
    @Transactional(rollbackFor = Exception.class)
    void applyRefund(String orderId, String currentUserId, boolean ownerCheck, boolean skipCheck) throws BizException;

    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2019/9/10 15:31</h3>
     * 订单确定退款
     * </p>
     *
     * @param orderId
     * @param refundAmount 本次退款金额 为null时全部退款
     */
    @Transactional(rollbackFor = Exception.class)
    void orderConfirmRefund(String orderId, Long refundAmount);

    /**
     * <p>
     * <h3>作者 keray</h3>
     * <h3>时间： 2021/11/24 2:50 下午</h3>
     * 订单搜索
     *
     * </p>
     *
     * @param
     * @return <p> {@link IPage<>} </p>
     * @throws
     */
    IPage<OrderModel> search(Map<String, Object> param, Page<OrderModel> page, boolean total);

    /**
     * 查询订单成交额
     *
     * @param param
     * @return
     */
    Long orderAmount(Map<String, Object> param);


    /**
     * 查询订单数量
     *
     * @param param
     * @return
     */
    long searchCount(Map<String, Object> param);

    /**
     * 代理商开课订单列表
     *
     * @param page
     * @param userIds
     * @param userId
     * @param orderStatus
     * @param startTime
     * @param endTime
     * @param type
     * @return
     */
    IPage<OrderModel> agentOpenCourse(Page<OrderModel> page, List<String> userIds, String userId, OrderStatus orderStatus, LocalDateTime startTime, LocalDateTime endTime, OrderType type);

    /**
     * 代理商订单金额
     *
     * @param userIds
     * @param userId
     * @param orderStatus
     * @param startTime
     * @param endTime
     * @param type
     * @return
     */
    Long agentMoney(List<String> userIds, String userId, OrderStatus orderStatus, LocalDateTime startTime, LocalDateTime endTime, OrderType type);

    /**
     * @param param
     * @return 获取开课的记录
     */
    IPage<OrderModel> openCourseList(Page<OrderModel> page,Map<String,Object> param);

    /**获取提码的记录
     * @param page
     * @param param
     * @return
     */
    IPage<OrderModel> openCodeList(Page<OrderModel> page,Map<String,Object> param);

    /**
     * 获取订单成交额折线图
     *
     * @param param
     * @return
     */
    List<Map> priceCountLine(Map<String, Object> param);
}
